import React, { useState, useEffect } from 'react';
import styles from './index.less';
import { Select, Spin, Tooltip } from 'antd';
import * as echarts from 'echarts/lib/echarts';
import PropTypes from 'prop-types';

import { CaretDownOutlined } from '#/utils/antdIcons';
import { HttpCode } from '#/utils/contacts.js';
import emitter from '#/utils/events';
import { TRDefault } from '@/components';
import { countNumber, NumberFormat2 } from '@/utils';
import {
  powerGenerationTable,
  utilizationAndFaultRate,
  operationSanKey,
  getSourceSelectData,
  getSourceSelectModalData,
} from '@/services/businessAnalysis';

import { ModuleHeader, TableTag, SituationTable } from '../components';
import CentreModal from '../components/CentreModal/index';
import EquipmentIndex from './Equipment';
import { filterTreeDataByIds } from '../helper';
import {
  handleFloatTooltip,
  handlePowerSituationNodes,
  operateColumns,
  getSanKeyOption,
  utilizationAndFaultRateTitle,
  setArray,
  flatArr,
  bySanKeyGetColumn,
} from './helper';

let expandList = [];

const convertTreeToArray = (data, treeMap = [], depth = 0) => {
  let lintDepth = depth;
  if (!(data && data.length)) return [];
  lintDepth++;
  return data.reduce((acc, cur) => {
    cur.depth = lintDepth;
    acc.push(cur);
    if (cur.children && cur.children.length) {
      convertTreeToArray(cur.children, treeMap, lintDepth);
    }
    if (cur.secondMenuList && cur.secondMenuList.length) {
      convertTreeToArray(cur.secondMenuList, treeMap, lintDepth);
    }
    return acc;
  }, treeMap);
};

const Operate = ({ dateObj, type, title }) => {
  let [userClassId, setuserClassId] = useState('0');
  let [powergenerationId, setpowergenerationId] = useState('全部');
  let [SourceSelectData, setSourceSelectData] = useState([]);
  let [sanKeyData, setSanKeyData] = useState([]); // 桑基图数据data
  let [centeruserTypeList, setcenteruserTypeList] = useState([]);
  let [allCenterTypeList, setAllCenterTypeList] = useState([]);
  let [resultstationList, setresultstationList] = useState([]);
  let [utilizationAndFaultRateData, setUtilizationAndFaultRateData] = useState({});
  let [powerSituationNodes, setPowerSituationNodes] = useState([]);
  let [isFirst, setIsFirst] = useState(true);
  let [sanKeyLoading, setSanKeyLoading] = useState(true);
  let [bottomLoading, setBottomLoading] = useState(true);
  let [powerSituationLoading, setPowerSituationLoading] = useState(true);
  let [powerLoading, setPowerLoading] = useState(true);
  let [powerSituation, setPowerSituation] = useState(['name', 'online']);
  useEffect(() => {
    setIsFirst(true);
    defaultFn();
    if (type === 'week') {
      setBottomLoading(false);
    }
  }, [dateObj.startDate, dateObj.endDate, type]);

  useEffect(() => {
    emitter.addListener('onChangeMnue', _onHandleResize);
    window.addEventListener('resize', _onHandleResize);
    _openCenterData('first');
    return () => {
      window.removeEventListener('resize', _onHandleResize);
      emitter.removeListener('onChangeMnue', _onHandleResize);
    };
  }, []);

  useEffect(() => {
    _getSourceSelectData();
    _openCenterData();
  }, [powergenerationId, userClassId]);
  useEffect(() => {
    _onGetSankeyData();
    _onPowerGenerationTable();
    _onUtilizationAndFaultRate();
  }, [centeruserTypeList, resultstationList]);

  const _onHandleResize = () => {
    let dom = document.getElementById('sanKey');
    if (dom) {
      let echartsDom = echarts.init(dom);
      setTimeout(() => {
        echartsDom.resize();
      }, 300);
    }
  };

  /* 接口参数封装 isAll -> projectIds是否传全部*/
  const _onGetParams = (isAll) => {
    const { startDate, endDate } = dateObj;
    let projectIds = resultstationList.length ? resultstationList : flatArr(centeruserTypeList);
    if (isAll) {
      projectIds = flatArr(allCenterTypeList);
    }
    return {
      startDate,
      endDate,
      projectIds: projectIds.map((n) => n.deptNum),
      type: type || '',
    };
  };
  /* 桑基图数据 */
  const _onGetSankeyData = async () => {
    setSanKeyLoading(true);
    let params = _onGetParams();
    if (!params.projectIds.length) {
      return;
    }
    let res = await operationSanKey(params);
    setSanKeyLoading(false);
    if (res && res.statusCode === HttpCode.SUCCESS) {
      let data = res.powerSituationBody || {};
      await setSanKeyData(data.nodes || []);
      _onGetSanKey(data);
    } else {
      setSanKeyData([]);
    }
  };
  // 获取发电情况表格展示
  const _onGetSanKey = (data) => {
    let dom = document.getElementById('sanKey');
    if (!dom) {
      return;
    }
    let echartsDom = echarts.init(dom);
    echartsDom.setOption(getSanKeyOption(data.nodes || [], data.links || []));
    echartsDom.resize();
    let setData = setPowerSituation;
    echartsDom.on('mouseover', (params) => {
      let arr = params.name.split('>').filter((n) => n);
      let columnKey = bySanKeyGetColumn(arr);
      if (columnKey[0] === columnKey[1]) {
        columnKey = [columnKey[0]];
      }
      setData(['name', ...columnKey]);
    });
  };
  /* 风电场可利用率、故障复现率 */
  const _onUtilizationAndFaultRate = async () => {
    let params = _onGetParams(true);
    if (type === 'week' || !params.projectIds.length || !isFirst) {
      return;
    }
    setIsFirst(false);
    setBottomLoading(true);
    let res = await utilizationAndFaultRate(params);
    setBottomLoading(false);
    if (res && res.statusCode === HttpCode.SUCCESS) {
      setUtilizationAndFaultRateData(res);
    }
  };
  /* 发电情况表格 */
  const _onPowerGenerationTable = async () => {
    setPowerSituationLoading(true);
    let params = _onGetParams();
    if (!params.projectIds.length) {
      return;
    }
    let deptBodyList = filterTreeDataByIds(centeruserTypeList, params.projectIds);
    let res = await powerGenerationTable({ deptBodyList, ...params });
    setPowerSituationLoading(false);
    if (res && res.statusCode === HttpCode.SUCCESS) {
      setPowerSituationNodes(handlePowerSituationNodes(res.powerSituationNodes));
    }
  };

  // 运营下拉框
  let _getSourceSelectData = async () => {
    setPowerLoading(true);
    let res = await getSourceSelectData();
    setPowerLoading(false);
    if (res && res.statusCode === HttpCode.SUCCESS) {
      let userTypeLists = res.userTypeList;
      userTypeLists.unshift({ code: '2', name: '全部', children: [] });
      setSourceSelectData(userTypeLists);
    } else {
      setSanKeyLoading(false);
      setBottomLoading(false);
      setPowerSituationLoading(false);
    }
  };

  let _onChangeSource = async (type, sourceId) => {
    //切换用户和发电
    if (type === 'one') {
      setuserClassId(sourceId);
      setpowergenerationId('全部');
    } else if (type === 'two') {
      setpowergenerationId(sourceId);
    }
    setresultstationList([]);
  };
  let defaultFn = () => {
    setpowergenerationId('全部');
    setuserClassId('0');
    setresultstationList([]);
  };
  let mapArr = (arr) => {
    let array = arr && arr.filter((item) => item.label === '项目');
    return array;
  };

  let _openCenterData = async (type) => {
    //中心弹框数据
    let res = await getSourceSelectModalData({
      assetManagementType: userClassId == 2 ? null : userClassId,
      powerGenerationType: powergenerationId === '全部' ? null : powergenerationId,
    });

    if (res && res.statusCode === HttpCode.SUCCESS) {
      if (type) {
        setAllCenterTypeList(res.userTypeList);
      }
      setcenteruserTypeList(res.userTypeList);
    } else {
      setSanKeyLoading(false);
      setBottomLoading(false);
      setPowerSituationLoading(false);
    }
  };

  let _openCenter = async () => {
    //中心弹框
    let echoArr = resultstationList.length > 0 ? resultstationList : [];
    let result = await CentreModal.show(centeruserTypeList, expandList, echoArr);

    if (result.index == 1) {
      setresultstationList(result.stationList);
      expandList = result.expandList;
    }
  };

  let array = [];
  let childrenone = SourceSelectData && SourceSelectData[1] && SourceSelectData[1].children;
  let childrentwo = SourceSelectData && SourceSelectData[2] && SourceSelectData[2].children;
  let setpowergenerationList =
    userClassId == 2
      ? setArray(childrenone, childrentwo)
      : userClassId == '0'
      ? childrenone
      : childrentwo;
  let obj = [{ code: '全部', name: '全部', children: [] }];
  let concatpowergenerationList = array.concat(obj, setpowergenerationList);
  let selectoneValue =
    userClassId == 2
      ? SourceSelectData && SourceSelectData[0] && SourceSelectData[0].code
      : userClassId || (SourceSelectData && SourceSelectData[0] && SourceSelectData[0].code);

  return (
    <div className={styles.operateBox}>
      <ModuleHeader title={title} />
      {powerLoading ? (
        <Spin spinning={powerLoading} style={{ width: '100%', height: 300, marginTop: 30 }} />
      ) : !powerLoading && (!SourceSelectData || !SourceSelectData.length) ? (
        <div className={styles.powerEmpty}>
          <TRDefault type={'lock'} />
        </div>
      ) : (
        <div>
          {/*头部选框*/}
          <Header
            SourceSelectData={SourceSelectData}
            concatpowergenerationList={concatpowergenerationList}
            _onChangeSource={_onChangeSource}
            resultstationList={resultstationList}
            mapArr={mapArr}
            centeruserTypeList={centeruserTypeList}
            selectoneValue={selectoneValue}
            powergenerationId={powergenerationId}
            _openCenter={_openCenter}
          />
          {/*桑基图*/}
          <Spin spinning={sanKeyLoading}>
            <div className={styles.snaKey}>
              {sanKeyData.length ? (
                <div id={'sanKey'} style={{ width: '100%', height: '100%', overflow: 'hidden' }} />
              ) : (
                <TRDefault type="emptysm" />
              )}
            </div>
          </Spin>
          {/*发电情况表格*/}
          <Spin spinning={powerSituationLoading}>
            <SituationTable
              config={{
                rowKey: 'id',
                style: { marginTop: 20 },
                scroll: { x: 1100, y: 500 },
              }}
              data={powerSituationNodes}
              columns={operateColumns(powerSituation, _onTableCol, 'powerSituation')}
            />
          </Spin>
          {/* 设备指标 */}
          <EquipmentIndex params={{ ...dateObj, type: type }} />

          {/*风电可利用率 故障复现率*/}
          <UtilizationAndFaultRate
            type={type}
            data={utilizationAndFaultRateData}
            _onTableCol={_onTableCol}
            loading={bottomLoading}
          />
        </div>
      )}
    </div>
  );
};

const Header = ({
  _openCenter,
  SourceSelectData,
  powergenerationId,
  concatpowergenerationList,
  selectoneValue,
  _onChangeSource,
  mapArr,
  resultstationList,
  centeruserTypeList,
}) => {
  return (
    <div className={styles.sanKeyHeader}>
      <div className={styles.texts}>
        发电情况<span>单位：万kWh</span>
      </div>
      {SourceSelectData.length &&
      concatpowergenerationList.length &&
      concatpowergenerationList.length ? (
        <div className={styles.selects}>
          <div className={styles.selectsdata}>
            <span>用户类型：</span>
            <Select
              dropdownMatchSelectWidth={false}
              bordered={false}
              onChange={(val) => _onChangeSource('one', val)}
              className={['sele', styles.dq_datepicker]}
              suffixIcon={<CaretDownOutlined style={{ fontSize: '12px', color: '#373E48' }} />}
              value={selectoneValue}
            >
              {SourceSelectData.map((item) => (
                <Select.Option key={item.code} value={item.code}>
                  {item.name}
                </Select.Option>
              ))}
            </Select>
          </div>
          <div className={styles.vline} />
          <div className={styles.selectsdata}>
            <span>发电类型：</span>
            <Select
              dropdownMatchSelectWidth={false}
              bordered={false}
              onChange={(val) => _onChangeSource('two', val)}
              className={['sele', styles.dq_datepicker]}
              suffixIcon={<CaretDownOutlined style={{ fontSize: '12px', color: '#373E48' }} />}
              value={powergenerationId}
            >
              {concatpowergenerationList &&
                concatpowergenerationList.map((item) => (
                  <Select.Option key={item && item.code} value={item && item.name}>
                    {item && item.name}
                  </Select.Option>
                ))}
            </Select>
          </div>
          <div className={styles.vline} />
          <div
            className={styles.centerText}
            onClick={() => {
              _openCenter();
            }}
          >
            <span>中心：</span>
            <span>
              {resultstationList.length == 0 ||
              (mapArr(convertTreeToArray(centeruserTypeList)) &&
                mapArr(convertTreeToArray(centeruserTypeList)).length == resultstationList.length)
                ? '全部'
                : `已选择${resultstationList.length}项`}
            </span>
            <span>
              <CaretDownOutlined style={{ fontSize: '12px' }} />
            </span>
          </div>
        </div>
      ) : (
        <div> </div>
      )}
    </div>
  );
};

Header.propTypes = {
  _openCenter: PropTypes.func,
  SourceSelectData: PropTypes.array,
  concatpowergenerationList: PropTypes.array,
  selectoneValue: PropTypes.node,
  _onChangeSource: PropTypes.func,
  mapArr: PropTypes.func,
  resultstationList: PropTypes.array,
  centeruserTypeList: PropTypes.array,
};

const _onTableCol = (text, data, columnsItem) => {
  let value = Number(text) || Number(text) === 0 ? Number(text) : text;
  // 表格展示值
  let precision = columnsItem.precision ? columnsItem.precision : 1;
  let tabValue =
    typeof value === 'number'
      ? NumberFormat2(columnsItem.percentage ? countNumber(text, 100, '*') : text, precision)
      : text;
  if (text === null) {
    return <span key={columnsItem.key}>-</span>;
  }
  let title = columnsItem.floatObj
    ? handleFloatTooltip(data, columnsItem)
    : tabValue + (columnsItem.percentage ? '%' : '');

  let tagValue = columnsItem.tagPercentage ? countNumber(value, 100, '*') : value;

  return (
    <span
      key={columnsItem.key}
      className={columnsItem.isTag && !columnsItem.tag ? styles.tableCol : ''}
    >
      {!columnsItem.tag ? (
        <Tooltip
          placement={columnsItem.placement || 'topLeft'}
          overlayClassName="overtoop"
          title={columnsItem.noToolTip ? '' : title}
        >
          <span
            className={styles.text}
            style={{ color: columnsItem.floatObj ? '#1E7CE8' : '#373E48', lineHeight: '22px' }}
          >
            {columnsItem.percentage ? tabValue + '%' : tabValue}
          </span>
        </Tooltip>
      ) : null}
      {columnsItem.tag ? (
        <TableTag
          isUp={Number(tagValue) > 0}
          percentage={!!columnsItem.tagPercentage}
          value={NumberFormat2(tagValue, precision)}
        />
      ) : null}
    </span>
  );
};

const UtilizationAndFaultRate = ({ type, data, _onTableCol, loading }) => {
  return (
    <Spin spinning={loading}>
      <div className={styles.bottomTable} style={{ marginBottom: 44 }}>
        {type !== 'week' &&
          Object.keys(utilizationAndFaultRateTitle).map((key, index) => {
            return (
              <div key={index + key} style={{ width: '50%' }}>
                <span className={styles.title}>{utilizationAndFaultRateTitle[key]}</span>
                <div className={styles[key]}>
                  {data[key] && data[key].length ? (
                    <SituationTable
                      config={{ rowKey: 'id', style: { marginTop: 20 } }}
                      data={data[key]}
                      columns={operateColumns(
                        Object.keys((data[key] && data[key][0]) || []),
                        _onTableCol,
                        key,
                      )}
                    />
                  ) : (
                    <div className={styles.empty}>
                      <TRDefault type="emptysm" />
                    </div>
                  )}
                </div>
              </div>
            );
          })}
      </div>
    </Spin>
  );
};

UtilizationAndFaultRate.propTypes = {
  type: PropTypes.string,
  data: PropTypes.object,
  _onTableCol: PropTypes.func,
  loading: PropTypes.bool,
};

Operate.propTypes = {
  type: PropTypes.string,
  dateObj: PropTypes.object,
  title: PropTypes.string,
};

export default Operate;
